# 装箱和拆箱

  • 装箱:把基本类型数据转成对应的包装类对象
  • 拆箱:把包装类对象转成对应的基本数据类型数据
  • 自动装箱:把一个基本类型变量直接赋给对应的包装类变量或 Object 变量
    • 在底层依然是手动装箱,使用的是 Xxx.valueOf() 方法
    • 因此,Object obj = 17; Object[] arr = {"A", 12, 3.14, true};
  • 自动拆箱:把包装类对象直接赋给对应的基本数据类型变量,或者包装类对象与基本数据类型变量使用“==”比较
    • 在底层依然是手动拆箱,使用的是 xxxValue() 方法
    • 因此,switch 语句也支持 byte, short, char, int 对应的包装类

基本类型包装类

  • 可以把基本类型的变量近似地当成对象使用,也可以把包装类的实例近似地当成基本类型的变量使用
  • 八大基本数据类型的包装类都都是最终类不可变类(对应的储存数值的成员变量 value 值使用 private final 修饰)
  • Byte、Short、Integer、Long、Float、Double、BigDecimal、BigInteger 类都是 Number 抽象类的子类,都是 Comparable<T> 接口的实现类
Integer intObj1 = new Integer(123);
Integer intObj2 = Integer.valueOf(123); // 推荐,带有缓存,相当于 Integer intObj1 = 123;
int num3 = intObj1.intValue(); // int num3 = new Integer(123);
Integer intObj4 = 123;  // 底层 Integer intObj4 = Integer.valueOf(123)
int num5 = intObj4; // 底层 int num5 = intObj4.intValue()
intObj4 == 123; // true,底层 intObj4.intValue() == 123

Object boolObj = true;
if (boolObj instanceof Boolean) {
    boolean b = (Boolean)boolObj;
    System.out.println(b);
}

Long longObj = 123L;
Objects.equals(longObj, intObj1); // false
longObj.equals(intObj1); // false
longObj.equals(123); // false
longObj.equals(123L); // true
longObj == 123; // true
longObj == 123L; // true

// java.lang.Long#equals
public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 包装类的常用操作方法

  1. 包装类中 public static final 修饰的字段:
    MIN_VALUEMAX_VALUESIZE(在内存中存储占的比特位数)、TYPE(对应基本类型的 Class 对象)

  2. 包装类的构造器,用于创建对应的包装类对象(xxx 类型的包装类 Xxx)

    • Xxx(xxx value):a. 装箱,如 Integer(int value) Boolean(boolean value)
    • Xxx(String str):f. 字符串 → 包装类
      1. Character 类没有此构造器
      2. Boolean(String str) // 如果 str 不为 null 且在忽略大小写时等于 "true",则创建一个表示 true 值的 Boolean 对象,否则创建一个表示 false 值的 Boolean 对象
      3. 当该字符串不能转换为适当格式时,抛出异常 NumberFormatException
  3. Short、Integer、Long、Float 和 Double 类中常用的静态方法

    • xxx sum(xxx a, xxx b):将两个数相加
    • xxx min(xxx a, xxx b):返回两个数的较小值, Math.min
    • xxx max(xxx a, xxx b):返回两个数的较大值, Math.max
    • int compare(xxx a, xxx b):比较两个数值,a 小于、等于或大于 b 则分别返回 -1、0 或 1
    • xxx getXxx(String nm, Xxx val):获取指定名称的系统属性值,如果没有则返回 val
  4. 包装类、基本类型、字符串之间的转换

Xxx类中的类方法 方法说明
Xxx valueOf(xxx value) a. 装箱(推荐,带有缓存)
Xxx valueOf(String s) f. 字符串 → 包装类
String toString(xxx value) c. 基本类型 → 字符串
xxx parseXxx(String s) d. 字符串 → 基本数据(Character 除外)
实例方法 方法说明
xxx xxxValue() b. 拆箱(Number 类)
char charValue() b. 拆箱
boolean booleanValue() b. 拆箱
String toString() e. 包装类 → 字符串
boolean equals(Object obj) g. 判断包装类对象的值是否相等,对象类型不同时返回 false
compareTo(T o) f. 该对象小于、等于或大于指定对象则分别返回 -1、0 或 1
  • c.基本类型 → 字符串:String String.valueOf(xxx value); // String 类中的类方法

包装类转换

# 包装类中的缓存设计(享元模式)

  • Byte、Short、Integer、Long:使用 cache 数组默认缓存了 -128~127 之间的整数自动装箱成的包装类对象
  • Character:使用 cache 数组默认缓存了 0~127 之间的整数自动装箱成的 Character 类对象

把一个在缓存区间内的整数通过 valueOf(xxx value) 装箱成包装类对象时,该对象引用 cache 数组的同一个数组元素通过 new 创建的包装类对象不是

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

// 通过 new 创建的包装类对象不是
public Integer(int value) {
    this.value = value;
}
1
2
3
4
5
6
7
8
9
10
Updated at: 2022-11-09 19:52:32